package com.gitee.shoes.crawler.core.nice;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
import com.gitee.shoes.crawler.bean.*;
import com.gitee.shoes.crawler.core.AbstractApiRequest;
import com.gitee.shoes.crawler.core.ApiRequestUtils;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author LYH
 */
@Slf4j
public class NiceApiRequest extends AbstractApiRequest {
    private interface Path {
        String host = "sneakers-wxmp.oneniceapp.com";
        String base = "https://" + host;
        String detail = base + "/product/info";
        String list = base + "/index/load_more";
        String buy_now_info = base + "/product/stocks";
        String last_sold_list = base + "/product/historytradelist";
        String pub_params = "b=microsoft&m=microsoft&pr=1&sw=414&sh=736&ww=414&wh=632&sbh=20&l=zh_CN&wxv=7.0.9&osv=Windows 10 x64&osn=windows&fss=15&sdkv=2.12.1&mpv=0.1.3";
    }

    /**
     * stockId含义猜测
     */
    private static final Map<Long, String> STOCK_MEANING = new HashMap<Long, String>() {{
        put(1L, "普通");
        put(16L, "预售");
        put(512L, "直送");
    }};

    @Override
    public ApiProductList productList(String keyword, Integer page, Integer limit, String nextKey, OrderMode orderMode) {
        String url = StrUtil.format("{}?{}", Path.list, Path.pub_params);
        NiceResp<ItemData> niceResp = request(Method.POST, url, StrUtil.format("search_key={}&nextkey={}&from=search", keyword,
                StrUtil.nullToEmpty(nextKey)), new TypeReference<NiceResp<ItemData>>() {
        });
        ItemData data = niceResp.getData();
        String nextKeyResult = data.getNextkey();
        List<ItemData_Products> products = data.getProducts();
        List<ApiProduct> productItems = products.stream().map(e -> new ApiProduct().setMainId(Convert.toStr(e.getId()))
                .setLogoUrl(e.getLogo()).setTitle(e.getName())
                .setMinSalePrice(e.getPrice())
                .setArticle(e.getSku()).setSoldInfo(Convert.toStr(e.getDealNum()))).collect(Collectors.toList());
        ApiProductList productItemList = new ApiProductList().setNextKey(nextKeyResult).setItemList(productItems);
        return productItemList;
    }

    @Override
    public ApiProduct productDetail(String mainId, String styleId) {
        String url = StrUtil.format("{}/{}?{}", Path.detail, mainId, Path.pub_params);
        NiceResp<DetailData> niceResp = request(Method.POST, url, null, new TypeReference<NiceResp<DetailData>>() {
        });
        DetailData data = niceResp.getData();
        DetailData_Product product = data.getProduct();

        String brandName = null;
        String authPrice = null;
        List<DetailData_DetailItems> detailItems = data.getDetailItems();
        for (DetailData_DetailItems detailItem : detailItems) {
            String title = detailItem.getTitle();
            if ("品牌".equals(title)) {
                brandName = detailItem.getSubTitle();
            } else if ("发售价".equals(title)) {
                authPrice = detailItem.getSubTitle();
            }
        }

//        List<ApiProductSize> productSizeList = new ArrayList<>();
//        List<DetailData_Product_SizeList> sizeList = product.getSizeList();
//        sizeList.forEach(e -> {
//            DetailData_Product_SizeList_Params params = e.getParams();
//            String size = ApiRequestUtils.handlerSize(params.getSize());
//            ApiProductSize productSize = new ApiProductSize().setPropertyValueId(Convert.toStr(params.getSizeId())).setSize(size);
//            productSizeList.add(productSize);
//        });

        List<DetailData_Product_Details> details = product.getDetails();
        List<String> imageList = details.stream().map(e -> e.getImgUrl()).collect(Collectors.toList());

        DetailData_TradeRecord tradeRecord = data.getTradeRecord();
        String soldInfo = tradeRecord.getSubTitle();

        ApiProduct productDetail = new ApiProduct()
                .setMainId(mainId)
                .setLogoUrl(product.getCover()).setTitle(product.getPrice())
                .setAuthPrice(authPrice).setSellDate(product.getReleaseTime())
                .setArticle(handlerArticle(product.getSku())).setBrandName(brandName)
                .setSizeList(null)
                .setImageList(imageList)
                .setSoldInfo(soldInfo);

        return productDetail;
    }

    @Override
    public ApiProductBuyNowList productBuyNowList(String mainId, String styleId, List<ApiProductSize> productSizeList) {
        String url = StrUtil.format("{}/{}?{}", Path.buy_now_info, mainId, Path.pub_params);
        NiceResp<BuyNowData> niceResp = request(Method.POST, url, null, new TypeReference<NiceResp<BuyNowData>>() {
        });

        BuyNowData data = niceResp.getData();
        List<BuyNowData_Stocks> stocks = data.getStocks();

        List<ApiProductBuyNow> productBuyNows = new ArrayList<>();
        stocks.forEach(stock -> {
            Long stockId = stock.getStockId();
            String tradeTypeName = STOCK_MEANING.get(stockId);
            if (tradeTypeName == null) {
                tradeTypeName = Convert.toStr(stockId);
            }
            String price = stock.getPrice();
            String size = ApiRequestUtils.handlerSize(stock.getSize());
            ApiProductBuyNow productBuyNow = new ApiProductBuyNow().setSize(size)
                    .setMinSalePrice(price).setTradeTypeName(tradeTypeName);
            productBuyNows.add(productBuyNow);
        });
        return new ApiProductBuyNowList().setBuyNowList(productBuyNows);
    }

    @Override
    public ApiProductLastSoldList productLastSoldList(String mainId, String styleId, Integer limit, String lastId) {
        // 默认50条
        String url = StrUtil.format("{}?{}", Path.last_sold_list, Path.pub_params);
        NiceResp<LastSoldData> niceResp = request(Method.POST, url, StrUtil.format("goods_id={}&nextkey={}&size_id=",
                mainId, StrUtil.nullToEmpty(lastId)
        ), new TypeReference<NiceResp<LastSoldData>>() {
        });
        LastSoldData data = niceResp.getData();
        List<LastSoldData_List> list = data.getList();
        List<ApiProductLastSold> productLastSolds = list.stream().map(e -> {
            ApiProductLastSold apiProductLastSold = new ApiProductLastSold()
                    .setTime(handlerFormatTime(e.getPurchaseTime()))
                    .setPrice(Convert.toLong(e.getPrice())).setSize(ApiRequestUtils.handlerSize(e.getSizeLabel()));
            apiProductLastSold.setSoldId(createSoldId(apiProductLastSold, e));
            return apiProductLastSold;
        }).collect(Collectors.toList());
        return new ApiProductLastSoldList().setLastId(data.getNextKey()).setLastSoldList(productLastSolds);
    }

    private String createSoldId(ApiProductLastSold apiProductLastSold, LastSoldData_List e) {
        return SecureUtil.md5(StrUtil.format("{}{}{}", e.getPurchaseTime(), e.getSizeLabel(), e.getPrice()));
    }

    private LocalDateTime handlerFormatTime(String purchaseTime) {
        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(Convert.toLong(purchaseTime), 0, ZoneOffset.ofHours(8));
        return dateTime;
    }


    @Override
    protected void fillRequest(HttpRequest request) {
        request.header("Cookie", "nice_sneakers_auth=");
    }

}